using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace SoulKeeper
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        static Game1 gameBase;
        Intro intro;
        Menu menu;
        Credits credits;
        Instruction instruction;
        public static bool pause;


        Player player;

        public Game1()
        {
            Engine.graphics = new GraphicsDeviceManager(this);
            this.graphics = Engine.graphics;

#if WINDOWS || XBOX
            Content.RootDirectory = "Content/content";
#else
            Content.RootDirectory = "game/jukeboy/jukeboyContent/content";
#endif
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.

            gameBase = this;
            Window.Title = "Projeto Final XNA";
            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 640;
            graphics.ApplyChanges();
            IsMouseVisible = true;

            Engine.spriteBatch = new SpriteBatch(GraphicsDevice);
            this.spriteBatch = Engine.spriteBatch;

            intro = new Intro(Content, Window);
            menu = new Menu(Content, Window);
            credits = new Credits(Content, Window);
            instruction = new Instruction(Content, Window);

            Engine.song = Content.Load<Song>("sounds/intro");
            //MediaPlayer.Play(Engine.song);
            Engine.songPlay = true;

            player = new Player(Content.Load<Texture2D>("players/player"), Window);
            player.player = 1;

            TileMap.Initialize(Content.Load<Texture2D>("bg/map_sheet"));

            Engine.current_state = Engine.GameStates.INTRO;
            Engine.current_level = Engine.GameLevels.LEVEL_1;

            Level.Initialize();
            Level.InitializeLevel((int)Engine.current_level);

            Camera.WorldRectangle = new Rectangle(0, 0, TileMap.TileWidth * TileMap.MapWidth,
                                                TileMap.TileHeight * TileMap.MapHeight);
            Camera.ViewPortWidth = 800;
            Camera.ViewPortHeight = TileMap.TileHeight * TileMap.MapHeight;
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            //Update of Engine


            Engine.gameTime = gameTime;
            Engine.keyboard = Keyboard.GetState();
            Engine.mouse = Mouse.GetState();
            Engine.gamepad = GamePad.GetState(PlayerIndex.One);

            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            if (!(pause))
            {
                switch (Engine.current_state)
                {
                    case Engine.GameStates.INTRO:
                        intro.Update();
                        break; //case INTRO
                    case Engine.GameStates.MENU:
                        menu.Update();
                        break; //case MENU
                    case Engine.GameStates.CREDITS:
                        credits.Update();
                        break;//case CREDITS
                    case Engine.GameStates.INSTRUCTION:
                        instruction.Update();

                        break; //case INSTURCTION
                    case Engine.GameStates.IN_GAME:


                        switch (Engine.current_level)
                        {
                            case Engine.GameLevels.LEVEL_1:

                                Level.Update(player, gameTime);
                                break;
                        }

                        break; //case IN_GAME
                }
                #region PAUSE
                if (Engine.keyboard.IsKeyDown(Keys.P) && !(Engine.last_keyboard.IsKeyDown(Keys.P)))
                {
                    pause = true;
                    if (Engine.songPlay)
                    {
                        Engine.songPlay = false;
                        MediaPlayer.Pause();
                    }
                }

                #endregion

                #region SOUND
                if (Engine.songPlay)
                {
                    if (Engine.keyboard.IsKeyDown(Keys.O) && !(Engine.last_keyboard.IsKeyDown(Keys.O)))
                    {
                        Engine.songPlay = false;
                        MediaPlayer.Pause();
                    }
                }
                else
                {
                    if (Engine.keyboard.IsKeyDown(Keys.O) && !(Engine.last_keyboard.IsKeyDown(Keys.O)))
                    {
                        Engine.songPlay = true;
                        MediaPlayer.Resume();
                    }
                }
                #endregion





            }
            else
            {

                if (Engine.keyboard.IsKeyDown(Keys.P) && !(Engine.last_keyboard.IsKeyDown(Keys.P)))
                {
                    pause = false;
                    MediaPlayer.Resume();
                    Engine.songPlay = true;
                }
            }
            Engine.last_keyboard = Engine.keyboard;
            Engine.last_gamepad = Engine.gamepad;
            Engine.last_mouse = Engine.mouse;

            base.Update(gameTime);
        }//Draw

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Blue);

            spriteBatch.Begin();


            switch (Engine.current_state)
            {
                case Engine.GameStates.INTRO:

                    intro.Draw();
                    break; //case INTRO
                case Engine.GameStates.MENU:
                    menu.Draw();
                    break;//case MENU
                case Engine.GameStates.CREDITS:
                    credits.Draw();
                    break;//case CREDITS
                case Engine.GameStates.INSTRUCTION:
                    instruction.Draw();

                    break; //case INSTURCTION
                case Engine.GameStates.IN_GAME:


                    switch (Engine.current_level)
                    {
                        case Engine.GameLevels.LEVEL_1:
                            Level.Draw(player, gameTime, true);


                            break;
                    }

                    break; //case IN_GAME
            }

            if (pause)
            {
                spriteBatch.Draw(Content.Load<Texture2D>("BG/PAUSE/pause"), new Rectangle(0, 0, 800, 640), Color.WhiteSmoke);
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }//Draw
        public static void EndGame()
        {
            Game1.gameBase.Exit();
        }
    }
}
